﻿using System;
using System.IO;
using Microsoft.Win32;
using PSE.Deployment.Engine;
using PSE.Deployment.Engine.Enums;
using PSE.Deployment.Engine.Interfaces;
using PSE.Deployment.SetupBase;
using PSE.Framework.Cryptography;
using Sinacor.Deployment.Setup.Main;
using Sinacor.Infra.Core.Licensing;
using PSE.Deployment.SetupBase.Parameter.Enums;

namespace Sinacor.Deployment.Setup.Install.Steps
{
    public class GenerateLicenceFile : BaseStep
    {
        private string _keyName = @"Software\Sinacor\{BFA0B223-5525-4367-A604-941AA9C65076}";
        private string _file = null;

        public GenerateLicenceFile(IStepGroup parent)
            : base(parent)
        {
            this.Id = "GenerateLicenceFile";
            this.Description = "Geração do arquivo de licença";

            this.ErrorBehavior = StepErrorBehavior.NotifyParent;
            this.NavigationBehavior = StepNavigationBehavior.NextCancel;

            this.ResetProgress(1);
        }

        public override void Execute()
        {
            _file = null;

            this.ResetProgress(1);

            const int KEY_SIZE = 1024;

            _file = Path.Combine(SetupMainFactory.GetInstance<SinacorMain>().Parameter.InstallationPath, @"Sinacor\License\Sinacor.lic");
            string originalFile = Path.Combine(SetupMainFactory.GetInstance<SinacorMain>().Parameter.InstalationSource, @"Bin\Sinacor\License\Sinacor.lic");

            this.IncrementProgress(_file);

            if (!Directory.Exists(Path.GetDirectoryName(_file)))
                Directory.CreateDirectory(Path.GetDirectoryName(_file));

            if (File.Exists(originalFile))
            {
                File.Copy(originalFile, _file);

                File.SetAttributes(_file, FileAttributes.Normal);
            }
            else if (!File.Exists(_file))
            {
                Licensing licensing = new Licensing();
                SignedLicensing signedLicensing = new SignedLicensing();

                licensing.Treaty = Treaty.Trial;

                if (Registry.CurrentUser.OpenSubKey(_keyName) == null)
                {
                    RegistryKey key = Registry.CurrentUser.CreateSubKey(_keyName);

                    licensing.GoodThru = DateTime.Now.AddDays(15);

                    key.SetValue("1AA9C650", RijndaelCryptographer.EncryptString(licensing.GoodThru.ToString()));
                }
                else
                {
                    licensing.GoodThru = Convert.ToDateTime(RijndaelCryptographer.DecryptString(Registry.CurrentUser.OpenSubKey(_keyName).GetValue("1AA9C650").ToString()));
                }

                DsaSigner.SignedData signedData = DsaSigner.Sign(Licensing.Serialize(licensing), KEY_SIZE);

                signedLicensing.Licensing = licensing;
                signedLicensing.PublicKey = signedData.Key;
                signedLicensing.Signature = signedData.Signature;
                signedLicensing.SaveMappedLicensingFile(_file);
            }
        }

        public override void Undo()
        {
            if (SetupMainFactory.GetInstance<SinacorMain>().Parameter.SetupMode == SetupMode.Install)
            {
                if (!string.IsNullOrEmpty(_file) && File.Exists(_file))
                    File.Delete(_file);

                this.DecrementProgress();
            }
        }
    }
}